package com.qk.management.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qk.common.PageResult;
import com.qk.common.enums.BizEnum;
import com.qk.common.exception.BizException;
import com.qk.common.util.JwtUtils;
import com.qk.dto.login.LoginDTO;
import com.qk.dto.user.AddUserDTO;
import com.qk.dto.user.QueryPageUserDTO;
import com.qk.dto.user.UpdateUserDTO;
import com.qk.entity.Role;
import com.qk.entity.User;
import com.qk.management.mapper.RoleMapper;
import com.qk.management.mapper.UserMapper;
import com.qk.management.service.UserService;
import com.qk.vo.login.LoginResultVO;
import com.qk.vo.user.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author:gzc
 * @Date: 2025/10/06 18:19
 * @Description:
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    private RoleMapper roleMapper;
    private static final String DEFAULT_PASSWORD = "123";

    @Override
    public PageResult<UserVO> queryListByPage(QueryPageUserDTO queryPageUserDTO) {
//        PageInfo<User> pageInfo = PageHelper.startPage(userQueryListByPageDto.getPage(), userQueryListByPageDto.getPageSize())
//                .doSelectPageInfo(() -> userMapper.queryPage(userQueryListByPageDto));
//        return PageResult.<User>builder().total(pageInfo.getTotal()).rows(pageInfo.getList()).build();
        Page<UserVO> page = this.baseMapper.queryPage(new Page<>(queryPageUserDTO.getPage(), queryPageUserDTO.getPageSize()), queryPageUserDTO);
        List<UserVO> records = page.getRecords();
        List<UserVO> collect = records.stream().map(userVO -> {
            String phone = DesensitizedUtil.mobilePhone(userVO.getPhone());
            userVO.setPhone(phone);
            return userVO;
        }).collect(Collectors.toList());
        return PageResult.<UserVO>builder().total(page.getTotal()).rows(collect).build();
    }

    @Override
    public void deleteByIds(List<Integer> ids) {
        boolean isNotEmpty = CollectionUtil.isNotEmpty(ids);
        if (!isNotEmpty) {
            BizException.throwBizException(BizEnum.PARAM_ERROR);
        }
        this.baseMapper.deleteByIds(ids);
    }

    @Override
    public void addUser(AddUserDTO addUserDTO) {
        boolean hasNull = BeanUtil.hasNullField(addUserDTO,  "password", "roleId", "deptId", "image", "remark","createTime", "updateTime");
        if (hasNull) {
            BizException.throwBizException(BizEnum.PARAM_ERROR);
        }
        User user = BeanUtil.copyProperties(addUserDTO, User.class);
        String rawPassword = new StringBuilder(user.getUsername()).append(DEFAULT_PASSWORD).toString();
        String encodedPassword = DigestUtils.md5DigestAsHex(rawPassword.getBytes());
        user.setPassword(encodedPassword);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        this.save(user);
    }

    @Override
    public User queryById(Integer id) {
        if (ObjectUtil.isEmpty(id)) {
            BizException.throwBizException(BizEnum.PARAM_ERROR);
        }
        return this.getById(id);
    }

    @Override
    public void updateUser(UpdateUserDTO updateUserDTO) {
        boolean hasNull = BeanUtil.hasNullField(updateUserDTO, "password", "roleId", "deptId", "image", "remark","createTime", "updateTime");
        if (hasNull) {
            BizException.throwBizException(BizEnum.PARAM_ERROR);
        }
        User user = BeanUtil.copyProperties(updateUserDTO, User.class);
        user.setUpdateTime(LocalDateTime.now());
        this.updateById(user);
    }

    @Override
    public List<User> queryAll() {
        return this.baseMapper.selectList(null);
    }

    @Override
    public List<User> queryByRole(String roleLabel) {
        if (!StringUtils.hasText(roleLabel)) {
            BizException.throwBizException(BizEnum.PARAM_ERROR);
        }
        return this.baseMapper.queryByRole(roleLabel);
    }

    @Override
    public List<User> queryByDept(Integer deptId) {
        if (Objects.isNull(deptId)) {
            BizException.throwBizException(BizEnum.PARAM_ERROR);
        }
        return this.baseMapper.queryByDept(deptId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public LoginResultVO login(LoginDTO loginDto) {
        boolean hasNull = BeanUtil.hasNullField(loginDto);
        if (hasNull) {
            BizException.throwBizException(BizEnum.PARAM_ERROR);
        }
        //查询用户是否存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, loginDto.getUsername());
        User user = this.baseMapper.selectOne(queryWrapper);
        if (Objects.isNull(user)) {
            BizException.throwBizException(BizEnum.Login_ERROR);
        }
        //密码校验
        //获取前端用户传递密码,对其进行MD5
        String userPassword = DigestUtils.md5DigestAsHex(loginDto.getPassword().getBytes());
        String encodedPassword = user.getPassword();
        boolean isChecked = ObjectUtil.equals(userPassword, encodedPassword);
        if (!isChecked) {
            BizException.throwBizException(BizEnum.Login_ERROR);
        }
        //检查用户状态
        if (user.getStatus() == 0) {
            BizException.throwBizException(BizEnum.STATUS_ERROR);
        }
        Role role = roleMapper.selectById(user.getRoleId());
        // 构造登录结果
        LoginResultVO loginResult = new LoginResultVO();
        loginResult.setId(user.getId());
        loginResult.setUsername(user.getUsername());
        loginResult.setName(user.getName());
        loginResult.setImage(user.getImage());
        loginResult.setRoleLabel(role.getLabel());
        //封装token
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", user.getId());
        claims.put("username", user.getUsername());
        String token = JwtUtils.generateToken(claims);
        loginResult.setToken(token);
        return loginResult;
    }
}
